package util

import (
	"fmt"
	"gitee.com/swsk33/gopher-fetch"
	"github.com/fatih/color"
	"sync"
	"time"
)

// RealTimeStatusLogger 实时下载状态输出实用类
type RealTimeStatusLogger struct {
	// 存放全部下载任务状态的列表，可实时更改其中的下载任务及其状态
	// 键：正在下载的identifier
	// 值：对应的下载状态 gopher_fetch.TaskStatus 对象指针
	StatusMap sync.Map
	// 互斥锁，可用于在实时输出状态时，对其它外部输出上锁
	Lock sync.Mutex
	// 光标输出偏移
	// 记录每一次实时输出后，光标的向下偏移的行数
	// 下一次再进行实时输出时，则会向上移动 pointerOffset 行以覆盖前面内容
	pointerOffset int
	// 颜色输出器对象
	printer *color.Color
}

// NewRealTimeStatusLogger 构造函数
//
//   - printColor 输出文字颜色
func NewRealTimeStatusLogger(printColor color.Attribute) *RealTimeStatusLogger {
	return &RealTimeStatusLogger{
		StatusMap:     sync.Map{},
		Lock:          sync.Mutex{},
		pointerOffset: 0,
		printer:       color.New(printColor),
	}
}

// RealTimePrint 实时在终端输出进度，该函数需要被不间断调用，每调用一次输出一次状态
func (log *RealTimeStatusLogger) RealTimePrint() {
	// 输出时上锁
	log.Lock.Lock()
	defer log.Lock.Unlock()
	// 清空已输出内容，置回光标
	if log.pointerOffset > 0 {
		fmt.Printf("\033[%dA", log.pointerOffset)
		log.pointerOffset = 0
	}
	// 实时输出
	log.StatusMap.Range(func(key, value any) bool {
		status := value.(*gopher_fetch.TaskStatus)
		process := float64(status.DownloadSize) / float64(status.TotalSize) * 100
		_, _ = log.printer.Printf("\033[2K影像：%s 已下载：%6.3f%% 速度：%s 预计剩余：%.1f秒\n", key, process, gopher_fetch.ComputeSpeed(status.Speed, time.Millisecond), gopher_fetch.ComputeRemainTime(status)/1000)
		log.pointerOffset++
		return true
	})
	time.Sleep(gopher_fetch.GlobalConfig.StatusNotifyDuration)
}